package com.jdwx.opengl.kotlin2

import android.annotation.SuppressLint
import android.view.View
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.yield
import okhttp3.RequestBody
import java.io.File
import java.lang.reflect.Constructor
import java.nio.charset.Charset
import kotlin.concurrent.thread
import kotlin.reflect.KClass
import kotlin.reflect.full.createInstance
import kotlin.reflect.jvm.javaConstructor

class Utils private constructor() {
    companion object {
        fun getScore(value: Int): Int {
            return 2 * value
        }
    }
}
object Utils2{
    fun getScore(value: Int): Int {
        return 2 * value
    }
}
data class Developer(val name: String, val age: Int)

fun mains(args: Array<String>) = runBlocking<Unit> {
    val fibonacci = sequence {
        yield(1L)
        var current = 1L
        var next = 1L
        while (true) {
            yield(next)
            val tmp = current + next
            current = next
            next = tmp
        }
    }

    print(fibonacci.take( 16 ).toList() )

     runBlocking {
        for (i in 0..99) {
             yield()
        }
    }
    Utils.getScore(10)
    Utils2.getScore( 100 )

    var dp = Developer("xibai",1)
    print(dp.age)

//    object : Thread() {
//        override fun run() {
//            Thread.sleep(3000)
//            println("A 使用 Thread 对象表达式: ${Thread.currentThread()}") }
//    }.start()
    var t = Thread{
        Thread.sleep(3000)
        println("A 使用 Thread 对象表达式: ${Thread.currentThread()}")
    }
    t.start()

}
/**
 * 获取文件全部内容字符串 * @param filename
 */
fun getFileContent(filename: String): String {

    val f = File(filename)
    return f.readText(Charset.forName("UTF-8"))
}
fun appendFileSync(text: String, destFile: String) {


    val f = File(destFile)
    if (!f.exists()) {
        f.createNewFile()
    }
    synchronized( Any() ){
        f.appendText(text, Charset.defaultCharset())
    }
}
@Volatile private var running = false
fun start() {
    running = true
    thread(start = true) {
        while (running) {
            println("Still running: ${Thread.currentThread()}")
        }
    }
}
fun stop() {
    running = false
    println("Stopped: ${Thread.currentThread()}")
}
class RequestWrapper {
    var url:String? = null
    var method:String? = null
    var body: RequestBody? = null
    var timeout:Long = 10
    internal var _success: (String) -> Unit = { }
    internal var _fail: (Throwable) -> Unit = {}
    fun onSuccess(onSuccess: (String) -> Unit) {
        _success = onSuccess
    }
    fun onFail(onError: (Throwable) -> Unit) {
        _fail = onError
    }
}

fun http(init: RequestWrapper.() -> Unit) {
    val wrap = RequestWrapper()
    wrap.init()
    executeForResult(wrap)
}
private fun executeForResult(wrap:RequestWrapper) {

}
//fun main(){
//    http{
//        url = "http://www.163.com/"
//        method = "get"
//        onSuccess {
//            //string -> L.i(string)
//        }
//        onFail {
//           // e -> L.i(e.message)
//        }
//    }
////    var b:Int? = null
////
////    println( b )
//
//    var a = "100"
//    a.let {
//        print("a==")
//    }
//    a.apply {
//
//        print("a==")
//    }
//    with( a ){
//
//    }
//    a.also{
//        //todo
//        print("a==")
//    }
//}

@SuppressLint("NewApi")
fun main(){

    fun aaa(b:Int){
        print("sss")
    }
    var aa = {b:Int-> print("sss")}
    aaa(10)
    aa(10)

    // 源代码
    fun test(a : Int , b : Int) : Int{
        return a + b
    }

    // lambda
    val test1 : (Int , Int) -> Int = {a , b -> a + b}
    // 或者
    val test2 = {a : Int , b : Int -> a + b}

    // 调用
    print( test1(3,5) )


    var arr = arrayOf(1,3,5,7,9)

    println( arr.filter { it<5 } )


    fun test(num1 : Int, bool : (Int) -> Boolean) : Int{
        return if (bool(num1)){ num1 } else 0
    }

    println(test(10) {it > 5})
    println( test(10, { it > 5 } ) )
    println(test(4) {it > 5})
    val map = mapOf("key1" to "value1","key2" to "value2","key3" to "value3")
    map.forEach( { (key,value)-> println("$key") } )
    map.forEach(  ){ (key,value)-> println("$key") }
    map.forEach{ (key,value)-> println("$key") }
    map.forEach{ key,value-> println("$key") }
    map.forEach{ key,_-> println("$key") }
    map.forEach{ (key,_)-> println("$key") }

    var bb = fun(x : Int , y : Int) : Int{
        return x+y
    }

    println(  p( bb(10,10) ) )

    bb = fun (x:Int, y:Int):Int = x+y

    println( bb(10,29) )

    fun cc (x:Int, y:Int):Int = x+y

    println( cc(10,2) )

    bb = fun(x:Int, y:Int) = x+y

    println( bb(10,29) )

    //带接受者的函数字面值

    val iop = fun Int.( other : Int) : Int = this + other

    println( 2.iop( 10 ) )

    class Html{
        constructor()
        constructor(a:Int,b:Int)
        constructor(a:Int)
        fun body(){
            println("body")
        }
    }

    fun htmlAction(init:Html.()->Unit) :Html{

        var html = Html()
        html.init()
        return html

    }


    htmlAction{
        body()
    }



    fun testq(b : Int): () -> Int{
        var a = 3
        return fun() : Int{
            a++
            return a + b
        }
    }

    val t = testq(3)
    println(t())
    println(t())
    println(t())



    var sum : Int = 0
    val arr1 = arrayOf(1,3,5,7,9)
    arr1.filter { it < 7  }.forEach { sum += it }

    println(sum)

    val numbers = listOf(1, 2, 3, 4)
    val numbersM = mutableListOf(1, 2, 3, 4)
    numbersM.add(2)

    print( numbersM.last() )

    println( numbersM.size )


    var aaaa = Html::class

    fun abc(gg: KClass<*>){
        var bb = gg.createInstance() as Html
        bb.body()

    }
    abc( Html::class )


    fun abc1(gg: KClass<*>){
        var bb = gg.constructors
        var cc = bb.stream().filter { it.parameters.size == 2 }
        var dd = cc.findAny()
        var ee = dd.get()
        var constructor = ee .javaConstructor

        var itemViewInstance = constructor!!.newInstance(2,3) as Html

        println("b==")

        itemViewInstance.body()

        println("===y")

    }
    abc1( Html::class )


    fun abc2(gg: Class<*>){
        var bb = gg.getDeclaredConstructor(Int::class.java,Int::class.java)
        var itemViewInstance = bb!!.newInstance(2,3) as Html

        println("b----")

        itemViewInstance.body()

        println("----y")

    }
    abc2( Html::class.java )



//    var v = aaaa.createInstance()
//
//    println( v.body() )



    for( s in 1..5 ){
        println( "0" )
    }





}